package com.lyons.easyweb.core.util;

import java.net.InetAddress;
import java.security.SecureRandom;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;

public class StringUtils {

	/**
	 * 获得系统信息(linux,windows)
	 * 
	 */
	public static String systemInfo() {
		// 系统属性,如：Windows,Linux
		String osName = System.getProperty("os.name").toLowerCase();

		if (Pattern.matches("linux.*", osName) || Pattern.matches("mac.*", osName)) { // Linux
			return "linux";
		} else if (Pattern.matches("windows.*", osName)) { // Windows
			return "windows";
		}
		return "linux";
	}

	/**
	 * 通过雪花算法获得一个ID
	 * 
	 */
	public static String getSnowflake() {
		Snowflake snowflake = IdUtil.getSnowflake(1, 1);
		return Convert.toStr(snowflake.nextId());
	}

	/**
	 * 生成16位不重复的随机数，含数字+大小写
	 */
	public static String guid() {
		StringBuilder sb = new StringBuilder();
		// 产生16位的强随机数
		Random rd = new SecureRandom();
		for (int i = 0; i < 16; i++) {
			// 产生0-2的3位随机数
			int type = rd.nextInt(3);
			switch (type) {
			case 0:
				// 0-9的随机数
				sb.append(rd.nextInt(10));
				break;
			case 1:
				// ASCII在65-90之间为大写,获取大写随机
				sb.append((char) (rd.nextInt(25) + 65));
				break;
			case 2:
				// ASCII在97-122之间为小写，获取小写随机
				sb.append((char) (rd.nextInt(25) + 97));
				break;
			default:
				break;
			}
		}
		return sb.toString();
	}

	/**
	 * 
	 * @param str 待检测字符串
	 * @return : 是数值返回true，否则返回false
	 * @Time : 2020年10月19日 - 下午3:14:52
	 * @Version : 0.0.1
	 * @TODO : 判断是否是正数数值类型【必须是正数，且小数后只能够是两位】
	 *
	 */
	public static boolean isNumber(String str) {
		Pattern pattern = Pattern.compile("^(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){0,2})?$"); // 判断小数点后2位的数字的正则表达式
		Matcher match = pattern.matcher(str);
		if (match.matches() == false) {
			return false;
		} else {
			return true;
		}
	}

	/**
	 * 获得UUID 字符串，去掉-
	 * 
	 */
	public static String uuid() {
		return UUID.randomUUID().toString().replace("-", "");
	}

	/**
	 * @return : Integer
	 * @TODO : 获取指定返回内的随机数
	 *
	 */
	public static Integer getRandom(Integer target) {
		Random random = new Random();
		return random.nextInt(target);
	}

	/**
	 * 获得请求的IP地址
	 * 
	 * @param request
	 */
	public static String ipAddres(HttpServletRequest request) {
		String ip = null;
		// X-Forwarded-For：Squid 服务代理
		String ipAddresses = request.getHeader("X-Forwarded-For");
		if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
			// Proxy-Client-IP：apache 服务代理
			ipAddresses = request.getHeader("Proxy-Client-IP");
		}
		if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
			// WL-Proxy-Client-IP：weblogic 服务代理
			ipAddresses = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
			// HTTP_CLIENT_IP：有些代理服务器
			ipAddresses = request.getHeader("HTTP_CLIENT_IP");
		}
		if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
			// X-Real-IP：nginx服务代理
			ipAddresses = request.getHeader("X-Real-IP");
		}
		// 有些网络通过多层代理，那么获取到的ip就会有多个，一般都是通过逗号（,）分割开来，并且第一个ip为客户端的真实IP
		if (ipAddresses != null && ipAddresses.length() != 0) {
			ip = ipAddresses.split(",")[0];
		}
		// 还是不能获取到，最后再通过request.getRemoteAddr();获取
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
			ip = request.getRemoteAddr();
		}
		return ip;
	}

	/**
	 * 获取服务器IP地址
	 */
	public static String hostAddres() {
		// 获取服务器的IP地址，便于后续追踪
		try {
			InetAddress address = InetAddress.getLocalHost();
			return address.getHostAddress();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 获得当前系统时间，年-月-日 时:分:秒
	 * 
	 */
	public static String getSystemTime() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		return sdf.format(new Date());
	}
}
